
/**
 * Project Name:cats-core-impl
 * File Name:MenuServiceImpl.java
 * Package Name:com.catsic.core.menu.service.impl
 * Date:2014年3月24日下午3:15:00
 * Copyright (c) 2014, oa.catsic.com All Rights Reserved.
 */
 
package com.catsic.core.menu.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.catsic.base.BaseServiceImpl;
import com.catsic.base.accordion.Accordion;
import com.catsic.base.exception.CatsicException;
import com.catsic.base.status.Status;
import com.catsic.base.tree.TreeInfo;
import com.catsic.core.constants.Constants;
import com.catsic.core.convert.Converts;
import com.catsic.core.entity.Menu;
import com.catsic.core.entity.Role;
import com.catsic.core.entity.User;
import com.catsic.core.exception.CatsicExceptionCode;
import com.catsic.core.form.MenuForm;
import com.catsic.core.menu.dao.MenuDao;
import com.catsic.core.menu.service.MenuService;
import com.catsic.core.organ.service.OrganService;
import com.catsic.core.role.service.RoleService;
import com.catsic.core.user.service.UserService;
import com.catsic.pub.drawer.service.DrawerService;
import com.catsic.pub.entity.Drawer;

/**
 * ClassName: MenuServiceImpl
 * Description: 菜单Service
 * date: 2014年3月24日 下午3:15:00
 * author: yangyd
 */
@Service("menuService")
public class MenuServiceImpl extends BaseServiceImpl<Menu, String> implements MenuService {
	
	@Autowired
	private MenuDao menuDao;
	
	@Autowired
	private OrganService organService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private DrawerService drawerService;
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#add(com.catsic.core.form.MenuForm)
	 **/
	@Override
	public MenuForm add(MenuForm form){
		Menu menu = new Menu();
		menu.setName(form.getName());
		/**
		 * 查询父节点
		 */
		Menu parent = null;
		if(form.getPid() != null){
			parent = findById(form.getPid());
		}
		menu.setParent(parent);
		menu.setCode(code(form.getPid()));
		menu.setPath(form.getPath());
		menu.setLevel(parent.getLevel() + 1);
		menu.setStatus(form.getStatus());
		menu.setSort(form.getSort());
		menu.setIcon(form.getIcon());
		menu.setDisplayArea(drawerService.findByCode(form.getDisplayAreaCode()));
		menu.setSystemType(drawerService.findByCode(form.getSystemTypeCode()));
		menu = super.add(menu);
		return Converts.convert(menu);
	}
	
	/**
	 * 生成编码规则
	 * @param pid
	 * @return
	 */
	private String code(String pid){
		/**
		 * 查询父节点下的所有子节点
		 */
		List<Menu> childs = menuDao.findByCodeIsNotNullAndParentIdOrderByCodeDesc(pid);
		Menu parent = null;
		if(StringUtils.isNotBlank(pid)){
			parent = findById(pid);
		}
		if(CollectionUtils.isNotEmpty(childs)){
			String code = childs.get(0).getCode();
			int length = code.length();
			return String.format("%0" + length + "d", Long.valueOf(code)+ 1);
		}else {
			return parent == null ? String.format("%0" + Constants.编码位数 + "d",0) : parent.getCode() + String.format("%0" + Constants.编码位数 + "d",0);
		}
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#update(com.catsic.core.form.MenuForm)
	 */
	public MenuForm update(MenuForm form){
		Menu menu = findById(form.getId());
		menu.setName(form.getName());
		menu.setPath(form.getPath());
		menu.setStatus(form.getStatus());
		menu.setSort(form.getSort());
		menu.setIcon(form.getIcon());
		Drawer displayArea = drawerService.findByCode(form.getDisplayAreaCode());
		Drawer systemType = drawerService.findByCode(form.getSystemTypeCode());
		menu.setDisplayArea(displayArea);
		menu.setSystemType(systemType);
		return Converts.convert(menu);
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findById(java.lang.Long)
	 */
	@Override
	public Menu findById(String id){
		Menu menu = getById(id);
		if(null == menu){
			throw new CatsicException(CatsicExceptionCode.实体不存在,Constants.MENU);
		}
		return menu;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findByLikeCode(java.lang.String)
	 */
	@Override
	public List<Menu> findByLikeCode(String code){
		return menuDao.findByLikeCode(code);
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findByCode(java.lang.String)
	 */
	@Override
	public Menu findByCode(String code) {
		Menu menu = menuDao.findByCode(code);
		if(menu == null){
			throw new CatsicException(CatsicExceptionCode.实体不存在,Constants.MENU);
		}
		return menu;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#cancel(java.lang.String)
	 **/
	@Override
	public void cancel(String id){
		Menu menu = findById(id);
		menu.setStatus(Status.无效);
		super.add(menu);
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#delete(java.lang.String)
	 */
	@Override
	public void delete(String id){
		Menu menu = findById(id);
		if(CollectionUtils.isNotEmpty(roleService.findRoleByMenuId(id))){
			throw new CatsicException(CatsicExceptionCode.资源管理_资源已绑定角色_无法删除);
		}
		delete(menu); 
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#active(java.lang.String)
	 */
	@Override
	public void active(String id){
		Menu menu = findById(id);
		menu.setStatus(Status.有效);
		super.add(menu);
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findUserMenuByUserId(java.lang.String)
	 */
	public List<Accordion> findUserMenuByUserId(String userId){
		List<Menu> listMenu = findMenuListById(userId);
		List<Accordion> listMenuForm = new ArrayList<Accordion>();
		for(Menu menu : listMenu){
			listMenuForm.addAll(userTree(menu));
		}
		return listMenuForm;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findUserMenuFormByUserId(java.lang.String)
	 */
	public List<MenuForm> findUserMenuFormByUserId(String userId){
		List<Menu> listMenu = findByUserIdOrderByCodeAsc(userId);
		List<MenuForm> listMenuForm = new ArrayList<MenuForm>();
		for(Menu menu : listMenu){
			listMenuForm.add(Converts.convert(menu));
		}
		return listMenuForm;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findMenuListById(java.lang.Long)
	 */
	@Override
	public List<Menu> findMenuListById(String id) {
		List<Menu> listMenu = new ArrayList<Menu>();
/*		if(Constants.ENTITY_ID.equals(id)){
			listMenu.addAll(findById(Constants.ENTITY_ID).getChilds());
			return listMenu;
		}*/
		User user = userService.findById(id);
		List<Role> setRole = user.getRoles();
		for(Role role : setRole){
			List<Menu> temp = role.getMenus();
			listMenu.addAll(temp);
		}
		listMenu = intersection(listMenu, findById(Constants.ENTITY_ID));
		return listMenu;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findOrganMenuListById(java.lang.Long)
	 */
	@Override
	public Menu findOrganMenuListById(String id) {
		Menu menu = findById(Constants.ENTITY_ID);
		List<Menu> listMenu = new ArrayList<Menu>();
		if(Constants.ENTITY_ID.equals(id)){
			return menu;
		}
		User user = userService.findById(id);
		List<Role> setRole = user.getOrgan().getRoles();
		for(Role role : setRole){
			List<Menu> temp = role.getMenus();
			listMenu.addAll(temp);
		}
		listMenu = intersection(listMenu, menu);
		menu.setChilds(listMenu);
		return menu;
	}
	
	/**
	 * 遍历menu所有子节点，与set集合求出交集
	 * @param set
	 * @param menu
	 * @return
	 */
	private List<Menu> intersection(List<Menu> set,Menu menu){
		List<Menu> listMenu = new ArrayList<Menu>();
		List<Menu> childs = new ArrayList<Menu>();
		Menu temp = null;
		/**
		 *求出两个集合交集 
		 **/
		listMenu = menu.getChilds();
		listMenu.retainAll(set);
		Iterator<Menu> iterator = listMenu.iterator();
		while(iterator.hasNext()){
			temp = iterator.next();
			childs = temp.getChilds();
			childs.retainAll(set);
			temp.setChilds(childs);
			
			Iterator<Menu> tempIter = temp.getChilds().iterator();
			while(tempIter.hasNext()){
				Menu t = tempIter.next();
				childs = t.getChilds();
				childs.retainAll(set);
				t.setChilds(childs);
			}
		}
		return listMenu;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findByName(java.lang.String)
	 */
	@Override
	public List<Menu> findByName(String name) {
		List<Menu> menus = menuDao.findByName(name);
		if(CollectionUtils.isEmpty(menus)){
			throw new CatsicException(CatsicExceptionCode.角色管理_菜单不能为空,Constants.MENU);
		}
		return menus;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#userTree(java.lang.Long)
	 */
	public List<Accordion> userTree(Menu t) {
		List<Accordion> list = new ArrayList<Accordion>();
		List<Accordion> all  = new ArrayList<Accordion>();
		Accordion form = Converts.accordion(t);
		all = iterator(t,all);
		list.add(recursive(form, all));
		return list;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#tree(java.lang.Object)
	 */
	@Override
	public List<Accordion> tree(String id) {
		Menu t = findOrganMenuListById(id);
		List<Accordion> list = new ArrayList<Accordion>();
		List<Accordion> all  = new ArrayList<Accordion>();
		Accordion form = Converts.accordion(t);
		all = iterator(t,all);
		list.add(recursive(form, all));
		return list;
	}
	
	/**
	 * 遍历所有的菜单
	 */
	private List<Accordion> iterator(Menu t,List<Accordion> listForm) {
		Accordion temp = Converts.accordion(t);
		listForm.add(temp);
		List<Menu> childs = t.getChilds();
		if(CollectionUtils.isNotEmpty(childs)){
			Iterator<Menu> iterator = t.getChilds().iterator();
			while (iterator.hasNext()) {
				t =  iterator.next();
				iterator(t,listForm);
			}
		}
		return listForm;
	}

	/**
	 * 递归处理菜单树
	 */
	private Accordion recursive(Accordion form,
			List<Accordion> list){
		Accordion temp = new Accordion();
		List<Accordion> childs = new ArrayList<Accordion>();
		for(Accordion item : list){
			if(form.getId()==item.getPid()){
				Accordion newItem = recursive(item, list);
				childs.add(newItem);
			}
		}
		temp.setId(form.getId());
		temp.setPid(form.getPid());
		temp.setText(form.getText());
		temp.setUrl(form.getUrl());
		if(CollectionUtils.isNotEmpty(childs)){
			temp.setChildren(childs);
		}
		return temp;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#findByUserIdOrderByCodeDesc(java.lang.String)
	 */
	public List<Menu> findByUserIdOrderByCodeAsc(String id){
		return menuDao.findByUserIdOrderByCodeAsc(id);
	}
	
	/** 
	 * @see com.catsic.core.menu.service.MenuService#findByPid(java.lang.String)
	 */
	public List<Menu> findByPid(String id){
		return menuDao.findByPid(id);
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#getTreeInfo(java.lang.String)
	 */
	public List<TreeInfo> getTreeInfo(String id){
		List<Menu> list = new ArrayList<Menu>();
		/**
		 * StringUtils.isBlank(id)条件为点击主页面菜单管理功能时触发
		 */
		if(StringUtils.equals(id, Constants.ENTITY_ID) || StringUtils.isBlank(id)){
			list = menuDao.findAllBySort();
		}else{
			list = menuDao.findByUserIdOrderByCodeAsc(id);
		}
				
		List<TreeInfo> listTreeInfo = new ArrayList<TreeInfo>();
		for(Menu menu : list){
			TreeInfo treeInfo = Converts.convertTree(menu);
			if(menu.getLevel() == 4L){
				treeInfo.setParent(false);
			}
			if(StringUtils.equals(menu.getId(), Constants.ENTITY_ID)){
				treeInfo.setOpen(true);
			}
			listTreeInfo.add(treeInfo);
		}
		return listTreeInfo;
	}
	
	/**
	 * @see com.catsic.core.menu.service.MenuService#query(java.lang.String)
	 */
	public List<MenuForm> query(String id){
		List<Menu> list = findByPid(id);
		List<MenuForm> listForm = new ArrayList<MenuForm>();
		for(Menu menu : list){
			MenuForm form = Converts.convert(menu);
			listForm.add(form);
		}
		return listForm;
	}
}
